package org.xiyu.yee.pjwto.trading;

import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.monster.piglin.Piglin;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.trading.ItemCost;
import net.minecraft.world.item.trading.MerchantOffer;
import net.minecraft.world.item.trading.MerchantOffers;
import org.xiyu.yee.pjwto.Constants;
import org.xiyu.yee.pjwto.data.PiglinLootData;

import java.util.*;
import java.util.Optional;

/**
 * 管理猪灵交易系统的核心类
 */
public class PiglinTradeManager {
    
    private static final Map<Item, PiglinTrade> CUSTOM_TRADES = new HashMap<>();
    
    /**
     * 初始化猪灵交易系统
     */
    public static void init() {
        loadCustomTrades();
        // 强制初始化战利品表（使用备用数据）
        PiglinLootData.initializeLootTable(null);
        Constants.LOG.info("Piglin trading system initialized with {} loot entries and {} custom trades", 
            PiglinLootData.getLootTable().size(), CUSTOM_TRADES.size());
    }
    
    /**
     * 初始化战利品表（需要在服务器启动后调用）
     */
    public static void initializeLootTable(net.minecraft.server.MinecraftServer server) {
        PiglinLootData.initializeLootTable(server);
        Constants.LOG.info("Piglin loot table initialized with {} entries", 
            PiglinLootData.getLootTable().size());
    }
    
    /**
     * 加载自定义交易配置
     */
    private static void loadCustomTrades() {
        // 配置文件由平台特定代码加载
        // 这里只添加一些默认的内置交易
        addCustomTrade(Items.DIAMOND, new PiglinTrade(
            new ItemStack(Items.GOLD_INGOT, 10), // 需要10个金锭
            ItemStack.EMPTY, // 不需要第二个物品
            new ItemStack(Items.DIAMOND, 1), // 获得1个钻石
            5, // 最多交易5次
            10 // 获得10点经验
        ));
        
        addCustomTrade(Items.NETHERITE_SCRAP, new PiglinTrade(
            new ItemStack(Items.GOLD_INGOT, 20),
            ItemStack.EMPTY,
            new ItemStack(Items.NETHERITE_SCRAP, 1),
            2,
            20
        ));
    }
    
    /**
     * 添加自定义交易
     */
    public static void addCustomTrade(Item resultItem, PiglinTrade trade) {
        CUSTOM_TRADES.put(resultItem, trade);
    }
    
    /**
     * 生成猪灵的交易列表
     */
    public static MerchantOffers generateTrades(Piglin piglin, ServerPlayer player) {
        MerchantOffers offers = new MerchantOffers();
        
        Constants.LOG.info("Generating trades for piglin, loot table size: {}, custom trades: {}", 
            PiglinLootData.getLootTable().size(), CUSTOM_TRADES.size());
        
        // 添加基于战利品表的交易
        addLootTableTrades(offers, piglin, player);
        
        // 添加自定义交易
        addCustomTrades(offers);
        
        // 按金锭需求量排序（从少到多）
        sortTradesByGoldCost(offers);
        
        Constants.LOG.info("Generated {} total trades for piglin", offers.size());
        
        return offers;
    }
    
    /**
     * 基于战利品表添加交易
     */
    private static void addLootTableTrades(MerchantOffers offers, Piglin piglin, ServerPlayer player) {
        Map<Item, PiglinLootData.LootEntry> lootTable = PiglinLootData.getLootTable();
        
        if (lootTable.isEmpty()) {
            Constants.LOG.warn("Piglin loot table is empty, no trades will be generated");
            return;
        }
        
        for (Map.Entry<Item, PiglinLootData.LootEntry> entry : lootTable.entrySet()) {
            Item item = entry.getKey();
            PiglinLootData.LootEntry lootEntry = entry.getValue();
            
            // 根据权重计算金锭需求量（权重越低需要越多金锭）
            int goldCost = calculateGoldCost(lootEntry.getWeight());
            
            // 使用战利品表中的平均数量
            int itemCount = Math.max(1, (int) Math.ceil(lootEntry.getAverageCount()));
            
            // 创建交易选项
            ItemCost cost = new ItemCost(Items.GOLD_INGOT, goldCost);
            ItemStack result = new ItemStack(item, itemCount);

            MerchantOffer offer = new MerchantOffer(
                    cost,                        // 第一个成本
                    Optional.empty(),            // 没有第二个成本
                    result,                      // 交易结果
                    getMaxUses(lootEntry.getWeight()),
                    getExperience(lootEntry.getWeight()),
                    0.2f
            );
            
            offers.add(offer);
            Constants.LOG.debug("Added loot table trade: {} x{} for {} gold ingots", 
                BuiltInRegistries.ITEM.getKey(item), itemCount, goldCost);
        }
    }
    
    /**
     * 添加自定义交易
     */
    private static void addCustomTrades(MerchantOffers offers) {
        for (PiglinTrade trade : CUSTOM_TRADES.values()) {
            // 获取第二个成本的 ItemStack
            ItemStack costBStack = trade.getCostB();

            // 创建 ItemCost 对象
            ItemCost costA = new ItemCost(trade.getCostA().getItem(), trade.getCostA().getCount());
            Optional<ItemCost> costB = costBStack.isEmpty() ? 
                Optional.empty() : 
                Optional.of(new ItemCost(costBStack.getItem(), costBStack.getCount()));

            // 创建 MerchantOffer 实例
            MerchantOffer offer = new MerchantOffer(
                    costA,
                    costB,
                    trade.getResult(),
                    trade.getMaxUses(),
                    trade.getExperience(),
                    0.2f
            );
            offers.add(offer);
            
            Constants.LOG.debug("Added custom trade: {} for {} gold ingots + {}", 
                BuiltInRegistries.ITEM.getKey(trade.getResult().getItem()),
                trade.getCostA().getCount(),
                costBStack.isEmpty() ? "nothing" : BuiltInRegistries.ITEM.getKey(costBStack.getItem()));
        }
    }
    
    /**
     * 根据权重计算金锭需求量
     */
    private static int calculateGoldCost(int weight) {
        // 权重越低，需要的金锭越多
        // 使用反比例关系：最大权重为8，最小金锭为1
        int maxWeight = 8;
        int minCost = 1;
        int maxCost = 16;
        
        // 确保权重至少为1
        weight = Math.max(1, weight);
        
        // 计算成本：高权重 = 低成本，低权重 = 高成本
        return Math.max(minCost, maxCost - (weight * (maxCost - minCost) / maxWeight));
    }
    
    /**
     * 获取最大使用次数（基于权重）
     */
    private static int getMaxUses(int weight) {
        // 稀有物品（低权重）使用次数较少
        if (weight <= 2) return 3;  // 最稀有
        if (weight <= 4) return 5;  // 稀有
        return 12; // 常见
    }
    
    /**
     * 获取经验值（基于权重）
     */
    private static int getExperience(int weight) {
        // 稀有物品（低权重）给予更多经验
        if (weight <= 2) return 10; // 最稀有
        if (weight <= 4) return 8;  // 稀有
        return 5; // 常见
    }
    
    /**
     * 按金锭需求量对交易进行排序
     */
    private static void sortTradesByGoldCost(MerchantOffers offers) {
        offers.sort((offer1, offer2) -> {
            int cost1 = offer1.getCostA().getCount();
            int cost2 = offer2.getCostA().getCount();
            return Integer.compare(cost1, cost2);
        });
    }
    
    /**
     * 检查是否可以与猪灵交易
     */
    public static boolean canTradeWithPiglin(Piglin piglin, ServerPlayer player) {
        // 猪灵必须是成年的
        if (piglin.isBaby()) {
            return false;
        }
        
        // 猪灵不能是僵尸化的
        if (piglin.isConverting()) {
            return false;
        }
        
        // 玩家必须空手
        if (!player.getMainHandItem().isEmpty()) {
            return false;
        }
        
        // 玩家必须在生存模式或冒险模式
        return !player.isCreative() && !player.isSpectator();
    }
}
